package org.example.rowing.controller.raceProcessController;

import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import lombok.extern.slf4j.Slf4j;
import org.example.rowing.controller.LaneExportController;
import org.example.rowing.controller.util.NavigationUtil;
import org.example.rowing.domain.Team;
import org.example.rowing.service.*;
import org.example.rowing.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.util.*;

@Controller
@Slf4j
public class SixteenToEighteenController {

    @FXML
    public Button nextRoundButton;
    @FXML
    public Button randomButton;
    @FXML
    public Button exportLaneButton;
    @FXML
    private Label rankLabel;
    @FXML
    private Label p11, p12, p13, p14, p15, p16, p21, p22, p23, p24, p25, p26, p31, p32, p33, p34, p35, p36; // 显示预赛队伍的Label
    @FXML
    private Label s11, s12, s13, s14, s15, s16, s21, s22, s23, s24, s25, s26; // 显示复赛队伍的Label
    @FXML
    private Label r11, r12, r13, r14, r15, r16, r21, r22, r23, r24, r25, r26;
    @FXML
    private Label f11, f12, f13, f14, f15, f16, f21, f22, f23, f24, f25, f26, f31, f32, f33, f34, f35, f36; // 显示决赛队伍的Label

    private Long raceId;
    private RaceVO raceVO;
    Map<String, Set<RoundScoreVO>> categoryMap = new HashMap<>();
    private Set<RoundScoreVO> p1Set = new HashSet<>();
    private Set<RoundScoreVO> p2Set = new HashSet<>();
    private Set<RoundScoreVO> p3Set = new HashSet<>();
    private Set<RoundScoreVO> s1Set = new HashSet<>();
    private Set<RoundScoreVO> s2Set = new HashSet<>();
    private Set<RoundScoreVO> r1Set = new HashSet<>();
    private Set<RoundScoreVO> r2Set = new HashSet<>();
    private Set<RoundScoreVO> f1Set = new HashSet<>();
    private Set<RoundScoreVO> f2Set = new HashSet<>();
    private Set<RoundScoreVO> f3Set = new HashSet<>();
    // 新增：标识抽签是否完成
    private boolean lotteryDone;
    private Integer f3ListLength; // 能够进入决赛B的艇数（11条艇时只有5条艇能进入，12条艇时只有6条艇能进入）
    private Integer s1ListLength; // 能够进入复赛的艇数
    private Integer s2ListLength; // 能够进入复赛的艇数
    private Integer p2ListLength;
    private Integer p3ListLength; // 预赛B组的艇数
    private final Object rankingLock = new Object();

    @Autowired
    private RaceProcessCommonService raceProcessCommonService;
    @Autowired
    private RaceInfoService raceInfoService;
    @Autowired
    private ProcessSixteenToEighteenBoatsService processSixteenToEighteenBoatsService;
    @Autowired
    private DrawLotteryService drawLotteryService;

    public static final List<String> teamLanes = Arrays.asList("", "A组3号", "A组4号", "A组2号", "A组5号", "A组1号", "A组6号",
            "B组3号", "B组4号", "B组2号", "B组5号", "B组1号", "B组6号",
            "C组3号", "C组4号", "C组2号", "C组5号", "C组1号", "C组6号");


    // 双击矩形区域显示分数输入框
    @FXML
    public void initialize(RaceVO raceVO) {
        this.raceId = raceVO.getId();
        this.raceVO = raceVO;
        this.lotteryDone = false;
        log.info("raceId---------------------------: {}", raceId);

        Map<RegistrationVO, String> lotteryResult = drawLotteryService.getLotteryResult(raceId);
        if (lotteryResult != null && !lotteryResult.isEmpty()) {
            lotteryDone = true;
        }

        List<RegistrationVO> teams = raceProcessCommonService.getRegistrationVOS(raceVO);
        p11.setText(teams.get(0).getTeam().getName());
        p12.setText(teams.get(1).getTeam().getName());
        p13.setText(teams.get(2).getTeam().getName());
        p14.setText(teams.get(3).getTeam().getName());
        p15.setText(teams.get(4).getTeam().getName());
        p16.setText(teams.get(5).getTeam().getName());
        p21.setText(teams.get(6).getTeam().getName());
        p22.setText(teams.get(7).getTeam().getName());
        p23.setText(teams.get(8).getTeam().getName());
        p24.setText(teams.get(9).getTeam().getName());
        p25.setText(teams.get(10).getTeam().getName());
//        p26.setText(teams.get(11).getTeam().getName());
        p31.setText(teams.get(12).getTeam().getName());
        p32.setText(teams.get(13).getTeam().getName());
        p33.setText(teams.get(14).getTeam().getName());
        p34.setText(teams.get(15).getTeam().getName());
        p35.setText(teams.get(15).getTeam().getName());

        p11.setOnMouseClicked(this::handleRectangleClick);
        p12.setOnMouseClicked(this::handleRectangleClick);
        p13.setOnMouseClicked(this::handleRectangleClick);
        p14.setOnMouseClicked(this::handleRectangleClick);
        p15.setOnMouseClicked(this::handleRectangleClick);
        p16.setOnMouseClicked(this::handleRectangleClick);
        p21.setOnMouseClicked(this::handleRectangleClick);
        p22.setOnMouseClicked(this::handleRectangleClick);
        p23.setOnMouseClicked(this::handleRectangleClick);
        p24.setOnMouseClicked(this::handleRectangleClick);
        p25.setOnMouseClicked(this::handleRectangleClick);
//        p26.setOnMouseClicked(this::handleRectangleClick);
        p31.setOnMouseClicked(this::handleRectangleClick);
        p32.setOnMouseClicked(this::handleRectangleClick);
        p33.setOnMouseClicked(this::handleRectangleClick);
        p34.setOnMouseClicked(this::handleRectangleClick);
        p35.setOnMouseClicked(this::handleRectangleClick);
        s11.setOnMouseClicked(this::handleRectangleClick);
        s12.setOnMouseClicked(this::handleRectangleClick);
        s13.setOnMouseClicked(this::handleRectangleClick);
        s14.setOnMouseClicked(this::handleRectangleClick);
        s15.setOnMouseClicked(this::handleRectangleClick);
        s21.setOnMouseClicked(this::handleRectangleClick);
        s22.setOnMouseClicked(this::handleRectangleClick);
        s23.setOnMouseClicked(this::handleRectangleClick);
        s24.setOnMouseClicked(this::handleRectangleClick);
        s25.setOnMouseClicked(this::handleRectangleClick);
        r11.setOnMouseClicked(this::handleRectangleClick);
        r12.setOnMouseClicked(this::handleRectangleClick);
        r13.setOnMouseClicked(this::handleRectangleClick);
        r14.setOnMouseClicked(this::handleRectangleClick);
        r15.setOnMouseClicked(this::handleRectangleClick);
        r16.setOnMouseClicked(this::handleRectangleClick);
        r21.setOnMouseClicked(this::handleRectangleClick);
        r22.setOnMouseClicked(this::handleRectangleClick);
        r23.setOnMouseClicked(this::handleRectangleClick);
        r24.setOnMouseClicked(this::handleRectangleClick);
        r25.setOnMouseClicked(this::handleRectangleClick);
        r26.setOnMouseClicked(this::handleRectangleClick);
        f11.setOnMouseClicked(this::handleRectangleClick);
        f12.setOnMouseClicked(this::handleRectangleClick);
        f13.setOnMouseClicked(this::handleRectangleClick);
        f14.setOnMouseClicked(this::handleRectangleClick);
        f15.setOnMouseClicked(this::handleRectangleClick);
        f16.setOnMouseClicked(this::handleRectangleClick);
        f21.setOnMouseClicked(this::handleRectangleClick);
        f22.setOnMouseClicked(this::handleRectangleClick);
        f23.setOnMouseClicked(this::handleRectangleClick);
        f24.setOnMouseClicked(this::handleRectangleClick);
        f25.setOnMouseClicked(this::handleRectangleClick);
        f26.setOnMouseClicked(this::handleRectangleClick);
        f31.setOnMouseClicked(this::handleRectangleClick);
        f32.setOnMouseClicked(this::handleRectangleClick);
        f33.setOnMouseClicked(this::handleRectangleClick);
        f34.setOnMouseClicked(this::handleRectangleClick);

        if (teams.size() == 16) {
            f3ListLength = 4;
            s1ListLength = 5;
            s2ListLength = 5;
            p2ListLength = 5;
            p3ListLength = 5;
        } else if (teams.size() == 17) {
            f3ListLength = 5;
            s1ListLength = 6;
            s2ListLength = 5;
            p2ListLength = 6;
            p3ListLength = 5;
            p26.setText(teams.get(16).getTeam().getName());
            p26.setOnMouseClicked(this::handleRectangleClick);
            s16.setOnMouseClicked(this::handleRectangleClick);
            f35.setOnMouseClicked(this::handleRectangleClick);
        } else if (teams.size() == 18) {
            f3ListLength = 6;
            s1ListLength = 6;
            s2ListLength = 6;
            p2ListLength = 6;
            p3ListLength = 6;
            p26.setText(teams.get(16).getTeam().getName());
            p36.setText(teams.get(17).getTeam().getName());
            p26.setOnMouseClicked(this::handleRectangleClick);
            p36.setOnMouseClicked(this::handleRectangleClick);
            s16.setOnMouseClicked(this::handleRectangleClick);
            s26.setOnMouseClicked(this::handleRectangleClick);
            f35.setOnMouseClicked(this::handleRectangleClick);
            f36.setOnMouseClicked(this::handleRectangleClick);
        } else {
            f3ListLength = null;
            s1ListLength = null;
            s2ListLength = null;
            p2ListLength = null;
            p3ListLength = null;
        }

        // 恢复分数信息
        restoreScores();
    }

    // 恢复分数信息并显示
    private void restoreScores() {
        categoryMap.clear();
        p1Set.clear();
        p2Set.clear();
        p3Set.clear();
        s1Set.clear();
        s2Set.clear();
        r1Set.clear();
        r2Set.clear();
        f1Set.clear();
        f2Set.clear();
        f3Set.clear();
        categoryMap.put("p1", p1Set);
        categoryMap.put("p2", p2Set);
        categoryMap.put("p3", p3Set);
        categoryMap.put("s1", s1Set);
        categoryMap.put("s2", s2Set);
        categoryMap.put("r1", r1Set);
        categoryMap.put("r2", r2Set);
        categoryMap.put("f1", f1Set);
        categoryMap.put("f2", f2Set);
        categoryMap.put("f3", f3Set);

        List<RoundScoreVO> roundScoreVOS = raceInfoService.loadRoundScoreVOByRaceId(raceId);
        for (RoundScoreVO roundScoreVO : roundScoreVOS) {
            String labelId = roundScoreVO.getLabelId();
            if (labelId == null) {
                continue;
            }
            Label label = findLabelById(labelId);
            String labelText = "";
            if (roundScoreVO.getScore() != null) {
                if (roundScoreVO.getStatus().equals("NORMAL")) {
                    double time = roundScoreVO.getScore();
                    String formattedTime = getFormattedTime(time);
                    labelText = " 用时：" + formattedTime;
                } else {
                    labelText = " " + roundScoreVO.getStatus();
                }
            }
            String text = roundScoreVO.getRegistrationVO().getTeam().getName() + "-" + roundScoreVO.getRegistrationVO().getRegistrationId();
            label.setText(text + labelText);
            Tooltip tooltip = new Tooltip(text + labelText);
            tooltip.setShowDelay(javafx.util.Duration.millis(500));
            label.setTooltip(tooltip);
            label.setUserData(roundScoreVO);
            if (roundScoreVO.getScore() != null) {
                raceProcessCommonService.mapFilling(label, roundScoreVO, categoryMap);
            }
        }
    }

    // 根据 labelId 找到对应的 Label
    private Label findLabelById(String labelId) {
        switch (labelId) {
            case "p11": return p11;
            case "p12": return p12;
            case "p13": return p13;
            case "p14": return p14;
            case "p15": return p15;
            case "p16": return p16;
            case "p21": return p21;
            case "p22": return p22;
            case "p23": return p23;
            case "p24": return p24;
            case "p25": return p25;
            case "p26": return p26;
            case "p31": return p31;
            case "p32": return p32;
            case "p33": return p33;
            case "p34": return p34;
            case "p35": return p35;
            case "p36": return p36;
            case "s11": return s11;
            case "s12": return s12;
            case "s13": return s13;
            case "s14": return s14;
            case "s15": return s15;
            case "s16": return s16;
            case "s21": return s21;
            case "s22": return s22;
            case "s23": return s23;
            case "s24": return s24;
            case "s25": return s25;
            case "s26": return s26;
            case "r11": return r11;
            case "r12": return r12;
            case "r13": return r13;
            case "r14": return r14;
            case "r15": return r15;
            case "r16": return r16;
            case "r21": return r21;
            case "r22": return r22;
            case "r23": return r23;
            case "r24": return r24;
            case "r25": return r25;
            case "r26": return r26;
            case "f11": return f11;
            case "f12": return f12;
            case "f13": return f13;
            case "f14": return f14;
            case "f15": return f15;
            case "f16": return f16;
            case "f21": return f21;
            case "f22": return f22;
            case "f23": return f23;
            case "f24": return f24;
            case "f25": return f25;
            case "f26": return f26;
            case "f31": return f31;
            case "f32": return f32;
            case "f33": return f33;
            case "f34": return f34;
            case "f35": return f35;
            case "f36": return f36;
            default: return null;
        }
    }

    // 处理矩形区域的双击事件
    private void handleRectangleClick(MouseEvent event) {
        if (event.getClickCount() == 2) {  // 双击事件
            Label source = (Label) event.getSource();
            log.info("当前双击事件为：{}", source);

            // 必须先完成抽签
            if (!lotteryDone) {
                showErrorDialog("请先完成抽签，再输入预赛成绩！");
                return;
            }

            if (source != null) {
                // 弹出输入框，让用户输入分数
                ScoreInputResult scoreInputResult = promptForTime();
                RoundScoreVO roundScoreVO = (RoundScoreVO) source.getUserData();
                if (scoreInputResult != null && roundScoreVO != null) {
                    roundScoreVO.setStatus(scoreInputResult.getStatus());
                    String text = roundScoreVO.getRegistrationVO().getTeam().getName() + "-" + roundScoreVO.getRegistrationVO().getRegistrationId();

                    if ("NORMAL".equals(scoreInputResult.getStatus())) {
                        roundScoreVO.setScore(scoreInputResult.getTime());
                        // 格式化为 x1:x2.x3 格式显示
                        String formattedTime = getFormattedTime(scoreInputResult.getTime());
                        source.setText(text + " 用时：" + formattedTime);
                        Tooltip tooltip = new Tooltip(text + " 用时：" + formattedTime);
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        source.setTooltip(tooltip);
                    } else {
                        roundScoreVO.setScore(Double.MAX_VALUE);
                        // 格式化为 x1:x2.x3 格式显示
                        source.setText(text + " " + scoreInputResult.getStatus());
                        Tooltip tooltip = new Tooltip(text + " " + scoreInputResult.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        source.setTooltip(tooltip);
                    }

                    // 保存用户输入的分数
                    raceInfoService.saveRoundScore(roundScoreVO);
                    if (roundScoreVO.getScore() != null) {
                        raceProcessCommonService.mapFilling(source, roundScoreVO, categoryMap);
                    }
                }
            }
        }
    }

    private static String getFormattedTime(double time) {
        int minutes = (int) (time / 60);
        int seconds = (int) (time % 60);
        int hundredths = (int) ((time * 100) % 100);
        return String.format("%d:%02d.%02d", minutes, seconds, hundredths);
    }

    // 自定义时间输入对话框
    private ScoreInputResult promptForTime() {
        Dialog<ScoreInputResult> dialog = new Dialog<>();
        dialog.setTitle("比赛用时／状态");
        dialog.setHeaderText("输入用时或直接选择状态");

        // OK / Cancel buttons
        ButtonType ok = new ButtonType("确认", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(ok, ButtonType.CANCEL);

        // layout: status combo + time fields
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 150, 10, 10));

        // status selector
        ComboBox<String> statusCombo = new ComboBox<>();
        statusCombo.getItems().addAll("NORMAL", "DNS", "DNF", "DSQ");
        statusCombo.setValue("NORMAL");

        TextField minutesField    = new TextField();
        TextField secondsField    = new TextField();
        TextField hundredthsField = new TextField();
        minutesField.setPromptText("分钟");
        secondsField.setPromptText("秒");
        hundredthsField.setPromptText("百分秒");

        grid.add(new Label("状态:"), 0, 0);
        grid.add(statusCombo,    1, 0);
        grid.add(new Label("分钟:"),   0, 1);
        grid.add(minutesField,   1, 1);
        grid.add(new Label("秒:"),      0, 2);
        grid.add(secondsField,   1, 2);
        grid.add(new Label("百分秒:"), 0, 3);
        grid.add(hundredthsField,1, 3);

        dialog.getDialogPane().setContent(grid);

        // when status ≠ NORMAL, disable the time inputs
        statusCombo.valueProperty().addListener((obs, old, val) -> {
            boolean timeNeeded = "NORMAL".equals(val);
            minutesField.setDisable(!timeNeeded);
            secondsField.setDisable(!timeNeeded);
            hundredthsField.setDisable(!timeNeeded);
        });

        // validation: if NORMAL, require time fields valid; else enable OK immediately
        Node confirm = dialog.getDialogPane().lookupButton(ok);
        BooleanBinding timeValid = Bindings.createBooleanBinding(() -> {
            return minutesField.getText().matches("\\d+") &&
                    secondsField.getText().matches("\\d{1,2}") &&
                    hundredthsField.getText().matches("\\d{1,2}") &&
                    Integer.parseInt(secondsField.getText()) < 60 &&
                    Integer.parseInt(hundredthsField.getText()) < 100;
        }, minutesField.textProperty(), secondsField.textProperty(), hundredthsField.textProperty());

        confirm.disableProperty().bind(
                Bindings.when(statusCombo.valueProperty().isEqualTo("NORMAL"))
                        .then(timeValid.not())
                        .otherwise(false)
        );

        // convert result
        dialog.setResultConverter(btn -> {
            if (btn == ok) {
                String status = statusCombo.getValue();
                if (!"NORMAL".equals(status)) {
                    // for DNS/DNF/DSQ, we treat score as MAX_VALUE
                    return new ScoreInputResult(Double.MAX_VALUE, status);
                } else {
                    int m = Integer.parseInt(minutesField.getText());
                    int s = Integer.parseInt(secondsField.getText());
                    int h = Integer.parseInt(hundredthsField.getText());
                    double total = m * 60.0 + s + h / 100.0;
                    return new ScoreInputResult(total, "NORMAL");
                }
            }
            return null;
        });

        return dialog.showAndWait().orElse(null);
    }

    public void handleNextRoundClick(ActionEvent event) {
        synchronized (rankingLock) {
            // 获取当前预赛、复赛、决赛的队伍列表
            List<RoundScoreVO> p1List = new ArrayList<>(p1Set);
            List<RoundScoreVO> p2List = new ArrayList<>(p2Set);
            List<RoundScoreVO> p3List = new ArrayList<>(p3Set);
            List<RoundScoreVO> s1List = new ArrayList<>(s1Set);
            List<RoundScoreVO> s2List = new ArrayList<>(s2Set);
            List<RoundScoreVO> r1List = new ArrayList<>(r1Set);
            List<RoundScoreVO> r2List = new ArrayList<>(r2Set);
            List<RoundScoreVO> f1List = new ArrayList<>(f1Set);
            List<RoundScoreVO> f2List = new ArrayList<>(f2Set);
            List<RoundScoreVO> f3List = new ArrayList<>(f3Set);

            // 对所有队伍按分数进行排序
            if (f1List.size() == 6 && f2List.size() == 6 && f3List.size() == f3ListLength) {
                // 处理决赛
                log.info("决赛队伍：{} 和 {} 和 {}", f1List, f2List, f3List);
                List<RoundScoreVO> rank = processSixteenToEighteenBoatsService.getRank(f1List, f2List, f3List, raceVO);
                StringBuilder finalRank = new StringBuilder();
                int i = 0;
                for (RoundScoreVO roundScoreVO : rank) {
                    i++;
                    String text = roundScoreVO.getRegistrationVO().getTeam().getName() + "-" + roundScoreVO.getRegistrationVO().getRegistrationId();
                    finalRank.append(i).append(": ").append(text).append("\n\n");
                }
                rankLabel.setText(finalRank.toString());
                log.info("排名：{}", rank);
            } else if (r1List.size() == 6 && r2List.size() == 6) {
                // 处理半决赛
                log.info("半决赛队伍：{} 和 {}", r1List, r2List);
                List<RoundScoreVO> halfFinals = processSixteenToEighteenBoatsService.getHalfFinals(r1List, r2List, raceId);
                // 更新决赛A的队伍
                for (int i = 0; i < 6; i++) {
                    RoundScoreVO vo = halfFinals.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("f1" + (i + 1));
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "决赛", label.getId(), teamLanes.get(i + 1), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        f1Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
                // 更新决赛B的队伍
                for (int i = 6; i < halfFinals.size(); i++) {
                    RoundScoreVO vo = halfFinals.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("f2" + (i - 5));
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "决赛", label.getId(), teamLanes.get(i + 1), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        f2Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
            } else if (s1List.size() == s1ListLength && s2List.size() == s2ListLength) {
                // 处理复赛
                log.info("复赛队伍：{} 和 {}", s1List, s2List);
                List<RoundScoreVO> advancingToFinals = processSixteenToEighteenBoatsService.semToHalfFinals(s1List, s2List, raceId);
                // 更新半决赛A的队伍
                for (int i = 0;i < 3; i++) {
                    RoundScoreVO vo = advancingToFinals.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("r1" + (i + 4));
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "半决赛", label.getId(), teamLanes.get(i + 4), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        r1Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
                // 更新半决赛B的队伍
                for (int i = 3; i < 6; i++) {
                    RoundScoreVO vo = advancingToFinals.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("r2" + (i + 1));
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "半决赛", label.getId(), teamLanes.get(i + 7), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        r2Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
                // 更新决赛C的队伍
                for (int i = 6; i < advancingToFinals.size(); i++) {
                    RoundScoreVO vo = advancingToFinals.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("f3" + (i - 5));
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "决赛", label.getId(), teamLanes.get(i + 7), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        f3Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
            } else if (p1List.size() == 6 && p2List.size() == p2ListLength && p3List.size() == p3ListLength) {
                // 处理预赛
                log.info("预赛队伍：{},{},{}", p1List, p2List, p3List);
                // 处理预赛：按分数降序排列
                List<RoundScoreVO> advancingToSemis = processSixteenToEighteenBoatsService.getAdvancingToSemis(p1List, p2List, p3List, raceId);
                List<RoundScoreVO> advancingToFinals = processSixteenToEighteenBoatsService.getAdvancingToFinals(p1List, p2List, p3List, raceId);
                // 更新复赛A的队伍
                for (int i = 0; i < s1ListLength; i++) {
                    RoundScoreVO vo = advancingToSemis.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("s1" + (i + 1)); // 找到复赛A的标签
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "复赛", label.getId(), teamLanes.get(i + 1), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        s1Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
                // 更新复赛B的队伍
                for (int i = s1ListLength; i < advancingToSemis.size(); i++) {
                    RoundScoreVO vo = advancingToSemis.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("s2" + (i - s1ListLength + 1));
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "复赛", label.getId(), teamLanes.get(i - s1ListLength + 7), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        s2Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
                // 更新半决赛A的队伍
                for (int i = 0; i < 3; i++) {
                    RoundScoreVO vo = advancingToFinals.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("r1" + (i + 1));
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "半决赛", label.getId(), teamLanes.get(i + 1), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        r1Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
                // 更新半决赛B的队伍
                for (int i = 3; i < advancingToFinals.size(); i++) {
                    RoundScoreVO vo = advancingToFinals.get(i);
                    RegistrationVO registrationVO = vo.getRegistrationVO();
                    Label label = findLabelById("r2" + (i - 2));
                    RoundScoreVO roundScore = new RoundScoreVO(raceId, registrationVO, "半决赛", label.getId(), teamLanes.get(i + 4), null);

                    if (vo.getStatus().equals("NORMAL")) {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                    } else {
                        label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId() + " " + vo.getStatus());
                        tooltip.setShowDelay(javafx.util.Duration.millis(500));
                        label.setTooltip(tooltip);
                        roundScore.setScore(Double.MAX_VALUE);
                        roundScore.setStatus(vo.getStatus());
                        r2Set.add(roundScore);
                    }

                    // 保存用户输入的分数
                    label.setUserData(roundScore);
                    raceInfoService.saveRoundScore(roundScore);
                }
            } else {
                showErrorDialog("当前比赛未结束，无法晋级下一轮。请输入当前比赛的所有成绩！");
            }

            // 更新赛制和分数显示
            log.info("晋级信息已更新");
        }
    }

    public void handleRandomClick(ActionEvent event) {
        log.info("进入抽签: {}", event.getSource());
        NavigationUtil.showPopup(
                "/fxml/rowingViews/raceProcessView/randomView.fxml",
                "查看抽签",
                randomButton.getScene().getWindow(),
                controller -> {
                    if (controller instanceof DrawLotteryController drawLotteryController) {
                        drawLotteryController.setConfirmCallback(this::updateLotteryResult);
                        drawLotteryController.initialize(raceId);
                    }
                }
        );
    }

    /**
     * 根据抽签结果更新预赛区域各标签的队伍名称。
     * 抽签结果为 Map<teamName, lane>，需根据预先约定的航道顺序更新对应标签。
     */
    private void updateLotteryResult(Map<RegistrationVO, String> lotteryResult) {
        // 构建航道 → 标签映射
        Map<String, Label> laneToLabel = new HashMap<>();
        laneToLabel.put("A组2号", p13);
        laneToLabel.put("A组3号", p11);
        laneToLabel.put("A组4号", p12);
        laneToLabel.put("A组5号", p14);
        laneToLabel.put("A组1号", p15);
        laneToLabel.put("A组6号", p16);
        laneToLabel.put("B组2号", p23);
        laneToLabel.put("B组3号", p21);
        laneToLabel.put("B组4号", p22);
        laneToLabel.put("B组5号", p24);
        laneToLabel.put("B组1号", p25);
        laneToLabel.put("B组6号", p26);
        laneToLabel.put("C组2号", p33);
        laneToLabel.put("C组3号", p31);
        laneToLabel.put("C组4号", p32);
        laneToLabel.put("C组5号", p34);
        laneToLabel.put("C组1号", p35);
        laneToLabel.put("C组6号", p36);

        for (Map.Entry<RegistrationVO, String> entry : lotteryResult.entrySet()) {
            String lane = entry.getValue();
            RegistrationVO registrationVO = entry.getKey();
            Label label = laneToLabel.get(lane);
            label.setText(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
            Tooltip tooltip = new Tooltip(registrationVO.getTeam().getName() + "-" + registrationVO.getRegistrationId());
            tooltip.setShowDelay(javafx.util.Duration.millis(500));
            label.setTooltip(tooltip);
            // 保存用户输入的分数
            RoundScoreVO roundScoreVOCondition = new RoundScoreVO();
            roundScoreVOCondition.setRegistrationId(registrationVO.getRegistrationId());
            roundScoreVOCondition.setRaceId(raceId);
            roundScoreVOCondition.setRound("预赛");
            List<RoundScoreVO> roundScoreVOS = raceInfoService.showRoundScoreByCondition(roundScoreVOCondition);
            RoundScoreVO roundScoreVO = roundScoreVOS.get(0);
            roundScoreVO.setLabelId(label.getId());
            label.setUserData(roundScoreVO);
            raceInfoService.saveRoundScore(roundScoreVO);
        }
        log.info("根据抽签结果更新后的预赛队伍顺序：{}", lotteryResult);
        lotteryDone = true;
    }


    // 弹出错误提示框
    private void showErrorDialog(String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("输入错误");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    @FXML
    public void handleExportLaneEvent(ActionEvent event) {
        // 打开添加赛事界面的逻辑
        log.info("开始选择导出项目");
        NavigationUtil.showPopup(
                NavigationUtil.viewMap.get(exportLaneButton.getId()),
                "选择导出确认单的队伍",
                exportLaneButton.getScene().getWindow(),
                controller -> {
                    if (controller instanceof LaneExportController) {
                        ((LaneExportController) controller).initialize(raceId);
                    }
                }
        );
    }
}
